
package com.wwy.monitor.util;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.autonavi.dyui.common.exception.BizException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpClientUtils {
    public static final String DEFAULT_CHARSETNAME = "UTF-8";
    public static final int DEFAULT_TIMEOUT = 20 * 1000;
    public static final int CONNECT_TIMEOUT = 3 * 1000;
    private static Logger LOGGER = LoggerFactory.getLogger(HttpClientUtils.class);

    public static String postJson(String url, String body) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity reqEntity = new StringEntity(body);
            reqEntity.setContentEncoding("UTF-8");
            reqEntity.setContentType("application/json");
            httpPost.setEntity(reqEntity);
// Create a custom response handler
            ResponseHandler<String> responseHandler = response -> {
                int status = response.getStatusLine().getStatusCode();
                if (status >= HttpStatus.SC_OK && status < HttpStatus.SC_MULTIPLE_CHOICES) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            };
            String responseBody = httpclient.execute(httpPost, responseHandler);
            return responseBody;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            httpclient.close();
        }
    }

    public static String postJsonNew(String url, String body) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpPost httpPost = new HttpPost(url);
            StringEntity reqEntity = new StringEntity(body);
//reqEntity.setContentEncoding("UTF-8");
            reqEntity.setContentType("application/json");
            httpPost.setEntity(reqEntity);
// Create a custom response handler
            ResponseHandler<String> responseHandler = response -> {
                int status = response.getStatusLine().getStatusCode();
                if (status >= HttpStatus.SC_OK && status < HttpStatus.SC_MULTIPLE_CHOICES) {
                    HttpEntity entity = response.getEntity();
                    return entity != null ? EntityUtils.toString(entity) : null;
                } else {
                    throw new ClientProtocolException("Unexpected response status: " + status);
                }
            };
            String responseBody = httpclient.execute(httpPost, responseHandler);
            return responseBody;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            httpclient.close();
        }
    }

    /**
     * åépostè¯·æ±ï¼参数ç¨mapæ¥æ¶
     *
     * @param url å°å
     * @param map 参数
     * @return è¿åå¼
     */
    public static String postMap(String url, Map<String, String> map) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        List<NameValuePair> pairs = new ArrayList<>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
//SecurityUtil.startSSRFNetHookChecking();
            HttpPost post = new HttpPost(url);
            post.setEntity(new UrlEncodedFormEntity(pairs, DEFAULT_CHARSETNAME));
            response = httpClient.execute(post);
            if (response == null) {
                LOGGER.error("è¯·æ±è¿åå¤±è´¥,responseä¸ºç©º");
                throw new BizException(-1, "è¯·æ±è¿åå¤±è´¥");
            }
            if (response.getStatusLine().getStatusCode() != 200) {
                LOGGER.error("è¯·æ±è¿åå¤±è´¥,statusCode:{}", (response.getStatusLine().getStatusCode()));
                throw new BizException(-1, "è¯·æ±è¿åå¤±è´¥");
            }
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                result = EntityUtils.toString(resEntity, DEFAULT_CHARSETNAME);
            }
            return result;
        } /*catch (SSRFUnsafeConnectionError e) {
LOGGER.error("è¯·æ±å¼å¸¸",e);
throw new BizException(-1,"è¯·æ±å¼å¸¸");
}*/ catch (Exception e) {
            LOGGER.error("è¯·æ±å¼å¸¸", e);
            throw new BizException(-1, "è¯·æ±å¼å¸¸");
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
// åæ­¢hook
//SecurityUtil.stopSSRFNetHookChecking();
        }
    }

    public static void releaseConnection(HttpEntity httpEntity) throws IOException {
        EntityUtils.consume(httpEntity);
    }

    /**
     * http getè¯·æ±,å°mapè½¬æ¢æurl参数,ä¼å¤ç¨è¿æ¥
     *
     * @param url
     * @param map
     * @return
     */
    public static String getDataAsStringFromUrl(String url, Map<String, String> map) {
        try {
            url = buildHttpURI(url, map);
            return Request.Get(url).socketTimeout(DEFAULT_TIMEOUT).connectTimeout(CONNECT_TIMEOUT).execute()
                    .returnContent().asString(Charset.forName(DEFAULT_CHARSETNAME));
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }

    /**
     * æ ¹æ®mapæé getçurl
     *
     * @param url
     * @param map
     * @return
     * @throws URISyntaxException
     */
    public static String buildHttpURI(String url, Map<String, String> map) {
        if (map == null || map.size() == 0) {
            return url;
        }
        URIBuilder builder = new URIBuilder();
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        try {
            return builder.setPath(url).setParameters(nameValuePairs).setCharset(Charset.forName(DEFAULT_CHARSETNAME))
                    .build().toString();
        } catch (URISyntaxException e) {
            throw new RuntimeException(e.getMessage(), e);
        }
    }
}